#include "EEGDevice.h"
#include <QDateTime>
#include <QDir>
#include <QCoreApplication>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlDatabase>
#include <QFile>
#include <QTextStream>
#include <QFileInfo>
#include <QStringList>
#include <cmath>
#include <complex>
#include <QDebug>
#include <QThread>
#include <algorithm>

// 定义常量
const int SAMPLE_RATE = 250;  // 采样率
const int FRAME_SIZE = 37;    // 帧大小
const int PROCESSING_BLOCK_SIZE = 250; // 处理块大小
const int CHANNELS = 3;       // 通道数
const int REF_CHANNELS = 2;   // 参考电极通道数
const int TOTAL_CHANNELS = 5; // 总通道数

EEGDevice::EEGDevice(QObject *parent)
    : BioSignalDevice(parent),
    m_serialPort(new QSerialPort(this)),
    m_portName("COM3"),
    m_baudRate(115200),
    m_processingTimer(new QTimer(this)),
    m_dbUpdateTimer(new QTimer(this)),
    m_sampleCount(0),
    m_isFrameStarted(false),
    m_connected(false),
    m_acquiring(false),
    m_delayedVisualization(true),
    m_frameCounter(0),
    m_batchThreshold(100),
    m_lowCutoff(0.5),      // 低截止频率
    m_highCutoff(100.0),    // 高截止频率
    m_samplingRate(SAMPLE_RATE), // 采样率
    m_enableNotchFilter(true),   // 启用陷波滤波
    m_notchFrequency(50.0),      // 陷波频率50Hz
    m_notchBandwidth(2.0),       // 陷波带宽2Hz
    m_enableHighpassFilter(true) // 启用高通滤波
{
    // 连接串口数据接收信号
    QObject::connect(m_serialPort, &QSerialPort::readyRead, this, &EEGDevice::readSerialData);

    // 连接数据处理定时器
    QObject::connect(m_processingTimer, &QTimer::timeout, this, &EEGDevice::processAccumulatedData);

    // 连接数据库更新定时器
    QObject::connect(m_dbUpdateTimer, &QTimer::timeout, this, &EEGDevice::updateVisualizationFromBuffer);

    // 初始化脑电通道数据缓冲区
    m_accumulatedData.resize(CHANNELS);
    for (int i = 0; i < CHANNELS; i++) {
        m_accumulatedData[i].reserve(PROCESSING_BLOCK_SIZE * 2);
    }

    // 初始化参考电极数据缓冲区
    m_referenceData.resize(REF_CHANNELS);
    for (int i = 0; i < REF_CHANNELS; i++) {
        m_referenceData[i].reserve(PROCESSING_BLOCK_SIZE * 2);
    }

    // 初始化数据存储
    m_rawData.clear();
    m_voltageData.clear();
    m_denoisedDataList.clear();

    // 初始化可视化缓冲区
    m_visualBuffer.clear();

    // 初始化滤波器
    initializeFilters();

    // 初始化通道历史数据，为每个通道创建独立的历史数据缓存
    m_channelHistory.resize(CHANNELS);

    // 初始化数据库工作线程
    m_dbThread = new QThread(this);
    m_dbWorker = new DatabaseWorker();
    m_dbWorker->moveToThread(m_dbThread);

    QObject::connect(m_dbThread, &QThread::started, m_dbWorker, &DatabaseWorker::process);
    QObject::connect(m_dbWorker, &DatabaseWorker::finished, m_dbThread, &QThread::quit);
    QObject::connect(m_dbWorker, &DatabaseWorker::finished, m_dbWorker, &DatabaseWorker::deleteLater);
    QObject::connect(m_dbThread, &QThread::finished, m_dbThread, &QThread::deleteLater);

    // 启动工作线程
    m_dbThread->start();

    qDebug() << "EEG设备初始化完成";
}


EEGDevice::~EEGDevice()
{
    if (isConnected()) {
        disconnect();
    }
    // 停止数据库工作线程
    if (m_dbWorker) {
        m_dbWorker->stop();
    }

    if (m_dbThread) {
        m_dbThread->quit();
        m_dbThread->wait();
    }
}

QString EEGDevice::getDeviceInfo() const
{
    return "三导脑电设备 - " + QString(m_connected ? "已连接" : "未连接") +
           " (采样率: 250Hz, 通道数: 3)";
}

void EEGDevice::initializeFilters()
{
    qDebug() << "初始化滤波器...";

    // 设置默认滤波器参数
    m_lowCutoff = 0.5;       // 低截止频率（高通滤波）
    m_highCutoff = 100.0;    // 高截止频率（低通滤波）
    m_samplingRate = SAMPLE_RATE; // 250Hz采样率
    m_enableNotchFilter = true;   // 启用陷波滤波
    m_notchFrequency = 50.0;      // 50Hz陷波（电源干扰）
    m_notchBandwidth = 2.0;       // 2Hz带宽
    m_enableHighpassFilter = true; // 启用高通滤波

    qDebug() << "滤波器初始化完成:";
    qDebug() << "  - 带通滤波: " << m_lowCutoff << "-" << m_highCutoff << "Hz";
    qDebug() << "  - 陷波滤波: " << (m_enableNotchFilter ? "启用" : "禁用")
             << " (" << m_notchFrequency << "Hz, 带宽" << m_notchBandwidth << "Hz)";
    qDebug() << "  - 高通滤波: " << (m_enableHighpassFilter ? "启用" : "禁用")
             << " (截止频率" << m_lowCutoff << "Hz)";
}


// FFT实现 - 用于频域滤波
void EEGDevice::fft(QVector<std::complex<double>> &x, bool inverse)
{
    int n = x.size();

    // 位反转排序
    int j = 0;
    for (int i = 0; i < n - 1; i++) {
        if (i < j) {
            std::swap(x[i], x[j]);
        }
        int k = n / 2;
        while (k <= j) {
            j -= k;
            k /= 2;
        }
        j += k;
    }

    // 蝶形运算
    for (int l = 2; l <= n; l *= 2) {
        double angle = 2 * M_PI / l * (inverse ? -1 : 1);
        std::complex<double> wl(cos(angle), sin(angle));
        for (int i = 0; i < n; i += l) {
            std::complex<double> w(1, 0);
            for (int j = 0; j < l / 2; j++) {
                std::complex<double> u = x[i + j];
                std::complex<double> v = x[i + j + l / 2] * w;
                x[i + j] = u + v;
                x[i + j + l / 2] = u - v;
                w *= wl;
            }
        }
    }

    // 对于IFFT，需要除以n
    if (inverse) {
        for (int i = 0; i < n; i++) {
            x[i] /= n;
        }
    }
}

// 带通滤波器实现 - 使用FFT方法
QVector<double> EEGDevice::applyBandpassFilter(const QVector<double> &data,
                                               double lowCutoff,
                                               double highCutoff,
                                               double samplingRate,
                                               int channelIndex)
{
    int n = data.size();

    // 检查输入数据是否有效
    if (n == 0) {
        qWarning() << "滤波器输入数据为空";
        return data;
    }

    // 获取当前通道的历史数据
    QVector<double> *lastProcessedDataPtr = nullptr;

    // 如果提供了有效的通道索引，使用对应通道的历史数据
    if (channelIndex >= 0 && channelIndex < m_channelHistory.size()) {
        lastProcessedDataPtr = &m_channelHistory[channelIndex];
    } else {
        // 如果没有提供通道索引或索引无效，使用静态变量（兼容旧代码）
        static QVector<double> fallbackLastProcessedData;
        lastProcessedDataPtr = &fallbackLastProcessedData;
    }

    QVector<double> &lastProcessedData = *lastProcessedDataPtr;

    // 创建扩展数据，包含上次处理的后半部分(如果有)
    QVector<double> extendedData;

    // 如果有上次处理的数据，添加到扩展数据的前部
    if (!lastProcessedData.isEmpty()) {
        extendedData = lastProcessedData;
        extendedData.append(data);
    } else {
        extendedData = data;
    }

    int extendedSize = extendedData.size();

    // 确保数据长度是2的幂，如果不是，则填充
    int paddedSize = 1;
    while (paddedSize < extendedSize) {
        paddedSize *= 2;
    }

    // 使用镜像填充而非零填充，减少边缘效应
    QVector<std::complex<double>> complexData(paddedSize, std::complex<double>(0, 0));

    // 复制数据到复数数组
    for (int i = 0; i < extendedSize; ++i) {
        complexData[i] = std::complex<double>(extendedData[i], 0);
    }

    // 镜像填充剩余部分
    for (int i = extendedSize; i < paddedSize; ++i) {
        int mirrorIndex = 2 * extendedSize - i - 1;
        if (mirrorIndex >= 0 && mirrorIndex < extendedSize) {
            complexData[i] = std::complex<double>(extendedData[mirrorIndex], 0);
        }
    }

    // 执行FFT
    fft(complexData, false);

    // 应用带通滤波器，强化高通特性
    double lowFreq = lowCutoff / samplingRate;
    double highFreq = highCutoff / samplingRate;

    for (int i = 0; i < paddedSize; ++i) {
        double freq;
        if (i <= paddedSize / 2) {
            freq = static_cast<double>(i) / paddedSize;
        } else {
            freq = static_cast<double>(i - paddedSize) / paddedSize;
        }

        freq = qAbs(freq);

        // 增强型高通滤波：使用过渡带来平滑高通特性
        if (m_enableHighpassFilter && freq < lowFreq) {
            // 在0到lowFreq之间使用平滑过渡
            double transitionWidth = lowFreq / 2;
            if (freq < lowFreq - transitionWidth) {
                // 完全衰减
                complexData[i] = std::complex<double>(0, 0);
            } else {
                // 在过渡带内使用余弦平滑过渡
                double transitionFactor = 0.5 * (1 - cos(M_PI * (freq - (lowFreq - transitionWidth)) / transitionWidth));
                complexData[i] *= transitionFactor;
            }
        }
        // 低通部分保持不变
        else if (freq > highFreq) {
            complexData[i] = std::complex<double>(0, 0);
        }
    }

    // 执行IFFT
    fft(complexData, true);

    // 提取实部作为结果，但只取原始数据长度
    QVector<double> result(n);

    // 如果有上次处理的数据，从扩展数据的后半部分提取结果
    int startIndex = lastProcessedData.isEmpty() ? 0 : lastProcessedData.size();

    for (int i = 0; i < n; ++i) {
        if (startIndex + i < paddedSize) {
            result[i] = complexData[startIndex + i].real();
        } else {
            result[i] = 0; // 安全处理，不应该发生
        }
    }

    // 保存当前批次的后半部分，用于下次处理
    int overlapSize = qMin(n, 125); // 使用半个处理块大小作为重叠
    lastProcessedData.clear();
    for (int i = n - overlapSize; i < n; ++i) {
        if (i >= 0) {
            lastProcessedData.append(data[i]);
        }
    }

    return result;
}

QVector<QVector<double>> EEGDevice::processEegData(const QVector<QVector<double>>& inputData)
{
    qDebug() << "开始处理EEG数据...";

    if (inputData.isEmpty() || inputData.size() < CHANNELS) {
        qWarning() << "输入数据不足" << CHANNELS << "个通道";
        return inputData;
    }

    // 检查输入数据是否有异常值
    bool hasInvalidData = false;
    for (int ch = 0; ch < inputData.size(); ch++) {
        for (int i = 0; i < inputData[ch].size(); i++) {
            if (std::isnan(inputData[ch][i]) || std::isinf(inputData[ch][i]) || std::abs(inputData[ch][i]) > 1e10) {
                qWarning() << "通道" << ch << "输入数据包含异常值:" << inputData[ch][i];
                hasInvalidData = true;
                break;
            }
        }
    }

    if (hasInvalidData) {
        qWarning() << "输入数据包含异常值，返回零值数组";
        QVector<QVector<double>> zeroData(CHANNELS);
        for (int ch = 0; ch < CHANNELS; ch++) {
            zeroData[ch].resize(inputData[0].size(), 0.0);
        }
        return zeroData;
    }

    // 检查参考电极数据是否足够
    bool hasReferenceData = (m_referenceData.size() >= REF_CHANNELS &&
                             m_referenceData[0].size() >= inputData[0].size() &&
                             m_referenceData[1].size() >= inputData[0].size());

    // 步骤1: 参考电极去噪（共模噪声消除）
    // 计算参考电极的平均值作为共模噪声
    QVector<double> referenceAvg;
    if (hasReferenceData) {
        referenceAvg.resize(inputData[0].size());
        for (int i = 0; i < referenceAvg.size(); i++) {
            // 计算两个参考电极的平均值
            referenceAvg[i] = (m_referenceData[0][i] + m_referenceData[1][i]) / 2.0;
        }
        qDebug() << "使用参考电极数据进行共模噪声去除";
    } else {
        qDebug() << "无参考电极数据，跳过共模噪声去除步骤";
    }

    // 从三个通道中减去参考电极信号（共模噪声去除）
    QVector<QVector<double>> refRemovedData(CHANNELS);
    for (int ch = 0; ch < CHANNELS; ch++) {
        refRemovedData[ch].resize(inputData[ch].size());
        for (int i = 0; i < inputData[ch].size(); i++) {
            if (hasReferenceData) {
                // 使用参考电极去噪: ch1_ref_removed = ch1 - ref
                refRemovedData[ch][i] = inputData[ch][i] - referenceAvg[i];
            } else {
                // 无参考电极，直接使用原始数据
                refRemovedData[ch][i] = inputData[ch][i];
            }
        }
    }

    // 步骤2: 应用50Hz陷波滤波（如果启用）
    QVector<QVector<double>> notchFilteredData(CHANNELS);
    if (m_enableNotchFilter) {
        qDebug() << "应用" << m_notchFrequency << "Hz陷波滤波...";
        for (int ch = 0; ch < CHANNELS; ch++) {
            notchFilteredData[ch] = applyNotchFilter(refRemovedData[ch],
                                                     m_notchFrequency,
                                                     m_notchBandwidth,
                                                     m_samplingRate);
        }
    } else {
        notchFilteredData = refRemovedData;
        qDebug() << "陷波滤波已禁用，跳过此步骤";
    }

    // 步骤3: 应用带通滤波（包含0.5Hz高通滤波）
    QVector<QVector<double>> filteredData(CHANNELS);
    for (int ch = 0; ch < CHANNELS; ch++) {
        // 应用带通滤波器，传入通道索引以便使用对应的历史数据
        filteredData[ch] = applyBandpassFilter(notchFilteredData[ch],
                                               m_lowCutoff,
                                               m_highCutoff,
                                               m_samplingRate,
                                               ch);
    }

    qDebug() << "EEG数据处理完成";
    return filteredData;
}


QVector<double> EEGDevice::parseFrame(const QByteArray &frame)
{
    // 存储所有通道的电压值（包括参考电极）
    QVector<double> allVoltages;

    // 存储脑电通道的电压值（仅通道3-5）
    QVector<double> eegVoltages;

    // 检查帧长度
    if (frame.size() != FRAME_SIZE) {
        qWarning() << "无效的帧长度:" << frame.size();
        return eegVoltages;
    }

    // 准备输入数据
    unsigned char rawbyte[FRAME_SIZE];

    // 复制帧数据并存储原始字节
    QVector<unsigned char> rawByteVector;
    for (int i = 0; i < FRAME_SIZE; ++i) {
        rawbyte[i] = static_cast<unsigned char>(frame.at(i));
        rawByteVector.append(rawbyte[i]);
    }

    // 存储原始数据
    m_rawData.append(rawByteVector);

    // 检查帧头和帧尾
    if (rawbyte[0] != 0xA0 || rawbyte[1] != 0x10 || rawbyte[36] != 0xC0) {
        qWarning() << "帧头或帧尾无效";
        return eegVoltages;
    }

    // 根据ADS1299数据帧结构解析数据
    // 跳过帧头(2字节)和状态信息(7字节)及时间戳(3字节)，从第12字节开始是通道数据
    // 每个通道3字节，共5个通道
    // 通道1-2是参考电极，通道3-5是脑电信号

    // 提取5个通道的数据
    for (int j = 0; j < TOTAL_CHANNELS; j++) {
        // 计算通道数据在帧中的偏移量：帧头(2) + 状态信息(7) + 时间戳(3) + 通道偏移(j*3)
        int offset = 2 + 7 + 3 + j * 3;

        // 确保不越界
        if (offset + 3 > frame.size()) {
            qWarning() << "通道数据越界";
            continue;
        }

        // 从帧中提取3字节数据
        QVector<int> dataChannel;
        for (int k = 0; k < 3; k++) {
            dataChannel.append(static_cast<int>(rawbyte[offset + k]));
        }

        // 将3字节十进制数组转换为24位整数
        int rawData = decimalArrayToHexNumber(dataChannel);

        // 将24位整数转换为电压值
        double voltage = rawToVoltage(rawData);

        // 存储所有通道的电压值
        allVoltages.append(voltage);

        // 分类存储参考电极和脑电信号
        if (j < REF_CHANNELS) {
            // 通道1-2是参考电极
            QMutexLocker locker(&m_dataMutex);
            m_referenceData[j].append(voltage);
        } else {
            // 通道3-5是脑电信号
            eegVoltages.append(voltage);
        }
    }

    // 存储电压值
    m_voltageData.append(eegVoltages);

    return eegVoltages;
}

// 将3字节十进制数组转换为24位整数
int EEGDevice::decimalArrayToHexNumber(const QVector<int> &decimalArray)
{
    if (decimalArray.size() != 3) {
        qWarning() << "十进制数组长度不是3";
        return 0;
    }

    // 将3个字节拼接成一个24位整数
    int result = 0;
    for (int i = 0; i < 3; i++) {
        result = (result << 8) | (decimalArray[i] & 0xFF);
    }

    // 处理符号位扩展 (24位有符号数转换为32位有符号数)
    if (result & 0x800000) {
        result |= 0xFF000000;  // 扩展符号位到32位
    }

    return result;
}

// 将24位整数转换为电压值
double EEGDevice::rawToVoltage(int rawData, double vref, double gain)
{
    // 注意：rawData已经在decimalArrayToHexNumber函数中完成了符号位扩展
    // 不需要再次进行符号位扩展

    // 转换为电压(微伏)，使用正确的公式
    double scale = vref / (gain * 8388607.0);  // 8388607.0 = 2^23-1
    double voltage = rawData * scale * 1e6;    // 转换为微伏

    return voltage;
}

void EEGDevice::processAccumulatedData()
{
    if (!m_acquiring) return;

    QMutexLocker locker(&m_dataMutex);
    try {
        // 确保所有通道都有足够的数据
        for (int ch = 0; ch < CHANNELS; ++ch) {
            if (m_accumulatedData[ch].size() < PROCESSING_BLOCK_SIZE) return;
        }
        for (int ch = 0; ch < REF_CHANNELS; ++ch) {
            if (m_referenceData[ch].size() < PROCESSING_BLOCK_SIZE) return;
        }

        // 从每个通道提取处理块大小的数据
        QVector<QVector<double>> channelData(CHANNELS);
        for (int ch = 0; ch < CHANNELS; ++ch) {
            channelData[ch] = m_accumulatedData[ch].mid(0, PROCESSING_BLOCK_SIZE);
        }

        // 处理数据
        QVector<QVector<double>> processedData = processEegData(channelData);

        // 添加到去噪数据列表和可视化缓冲区
        m_denoisedDataList.append(processedData);
        m_visualBuffer.append(processedData);

        // 限制可视化缓冲区大小
        while (m_visualBuffer.size() > 80) {
            m_visualBuffer.removeFirst();
        }

        // 将处理后的数据批次添加到数据库写入队列
        if (m_dbWorker) {
            // 获取当前时间戳
            qint64 currentTimestamp = QDateTime::currentMSecsSinceEpoch();

            // 创建EEG数据插入任务，传入处理后的数据批次
            EegInsertTask* task = new EegInsertTask(processedData, currentTimestamp, 1); // 1为默认被试ID
            m_dbWorker->addTask(task);
        }

        // 修改：减少每次移除的数据量，保留更多重叠数据
        // 原来是 PROCESSING_BLOCK_SIZE/3 (约83点)，改为更小的值
        int removeSize = PROCESSING_BLOCK_SIZE/5;  // 每次只移除50个点，保留200个点的重叠

        // 从累积数据中移除已处理的部分，但保留更多重叠
        for (int ch = 0; ch < CHANNELS; ++ch) {
            if (m_accumulatedData[ch].size() >= removeSize) {
                m_accumulatedData[ch].remove(0, removeSize);
            }
        }
        for (int ch = 0; ch < REF_CHANNELS; ++ch) {
            if (m_referenceData[ch].size() >= removeSize) {
                m_referenceData[ch].remove(0, removeSize);
            }
        }

        // 更新样本计数
        m_sampleCount -= removeSize;

    } catch (...) {
        // 异常处理
    }
}

void EEGDevice::updateVisualizationFromBuffer()
{
    if (!m_delayedVisualization || !m_acquiring) {
        return;
    }

    try {
        if (m_visualBuffer.isEmpty()) {
            return;
        }

        // 计算缓冲区中总数据点数
        int totalPointsAvailable = 0;
        for (const auto& batch : m_visualBuffer) {
            if (!batch.isEmpty() && !batch[0].isEmpty()) {
                totalPointsAvailable += batch[0].size();
            }
        }

        // 如果缓冲区数据不足，等待更多数据
        const int minRequiredPoints = 250; // 至少需要1秒的数据(250Hz)
        if (totalPointsAvailable < minRequiredPoints) {
            return;
        }

        // 设置显示窗口大小为2秒(500点)
        const int displayWindowSize = 500;

        // 设置每次更新的点数
        const int pointsPerUpdate = 10; // 每次更新50个点

        // 计算延迟时间(以数据点为单位)，使用缓冲区后部分的数据
        // 这样可以确保有足够的历史数据用于平滑显示
        int delayPoints = qMax(0, totalPointsAvailable - displayWindowSize);

        // 初始化时间戳（如果是第一次）
        if (m_lastTimestamp == 0) {
            m_lastTimestamp = QDateTime::currentMSecsSinceEpoch();
        }

        // 每个数据点的时间间隔为4毫秒(250Hz采样率对应的时间间隔)
        const double timeInterval = 4.0;

        // 创建一个临时数组来存储所有要显示的数据点
        QVector<double> displayPoints;
        QVector<qint64> displayTimestamps;

        // 从缓冲区中收集要显示的数据点
        int collectedPoints = 0;
        int batchIndex = 0;
        int pointIndexInBatch = 0;
        int remainingPointsToSkip = delayPoints;

        // 首先跳过延迟点数
        while (remainingPointsToSkip > 0 && batchIndex < m_visualBuffer.size()) {
            const auto& batch = m_visualBuffer[batchIndex];
            if (batch.isEmpty() || batch[0].isEmpty()) {
                batchIndex++;
                continue;
            }

            int pointsInBatch = batch[0].size();
            if (remainingPointsToSkip >= pointsInBatch) {
                // 整个批次都要跳过
                remainingPointsToSkip -= pointsInBatch;
                batchIndex++;
            } else {
                // 只跳过批次中的部分点
                pointIndexInBatch = remainingPointsToSkip;
                remainingPointsToSkip = 0;
            }
        }

        // 然后收集要显示的点
        while (collectedPoints < displayWindowSize && batchIndex < m_visualBuffer.size()) {
            const auto& batch = m_visualBuffer[batchIndex];
            int ch = 0; // 只处理第一个通道

            if (batch.isEmpty() || batch[ch].isEmpty()) {
                batchIndex++;
                continue;
            }

            // 从当前批次中收集点
            while (pointIndexInBatch < batch[ch].size() && collectedPoints < displayWindowSize) {
                displayPoints.append(batch[ch][pointIndexInBatch]);
                displayTimestamps.append(m_lastTimestamp + static_cast<qint64>(collectedPoints * timeInterval));
                collectedPoints++;
                pointIndexInBatch++;
            }

            // 如果当前批次处理完毕，移动到下一个批次
            if (pointIndexInBatch >= batch[ch].size()) {
                batchIndex++;
                pointIndexInBatch = 0;
            }
        }

        // 如果没有收集到足够的点，等待更多数据
        if (displayPoints.size() < pointsPerUpdate) {
            return;
        }

        // 应用平滑处理
        // 使用移动平均平滑处理，但保持波形特征
        const int smoothingWindow = 5; // 平滑窗口大小
        QVector<double> smoothedPoints = displayPoints;

        if (displayPoints.size() >= smoothingWindow) {
            for (int i = smoothingWindow/2; i < displayPoints.size() - smoothingWindow/2; i++) {
                // 计算当前点与前后点的差值
                double prevDiff = std::abs(displayPoints[i] - displayPoints[i-1]);
                double nextDiff = std::abs(displayPoints[i] - displayPoints[i+1]);

                // 如果差值超过阈值，应用平滑
                if (prevDiff > 20.0 || nextDiff > 20.0) {
                    double sum = 0;
                    for (int j = -smoothingWindow/2; j <= smoothingWindow/2; j++) {
                        sum += displayPoints[i + j];
                    }
                    smoothedPoints[i] = sum / smoothingWindow;
                }
            }
        }

        // 每次只发送部分点，以平滑显示
        int startIndex = 0;
        int endIndex = qMin(pointsPerUpdate, smoothedPoints.size());

        // 发送数据点
        for (int i = startIndex; i < endIndex; i++) {
            QVector<double> point;
            point.append(smoothedPoints[i]); // FP1
            point.append(0); // FPZ - 占位
            point.append(0); // FP2 - 占位

            emit allChannelsDataReady(point);

            QVector<double> channelPoint;
            channelPoint.append(smoothedPoints[i]);

            emit dataReady(channelPoint, displayTimestamps[i]);
        }

        // 更新最后的时间戳
        if (endIndex > startIndex) {
            m_lastTimestamp = displayTimestamps[endIndex - 1] + static_cast<qint64>(timeInterval);
        }

        // 移除旧数据，但保留足够的数据以确保连续性
        // 只有当缓冲区变得非常大时才移除数据
        if (m_visualBuffer.size() > 50) {
            int batchesToRemove = m_visualBuffer.size() - 40; // 保留40个批次
            for (int i = 0; i < batchesToRemove; i++) {
                if (!m_visualBuffer.isEmpty()) {
                    m_visualBuffer.removeFirst();
                }
            }
        }

    } catch (const std::exception& e) {
        qWarning() << "从缓冲区更新可视化时发生异常:" << e.what();
    } catch (...) {
        qWarning() << "从缓冲区更新可视化时发生未知异常";
    }
}

void EEGDevice::updateVisualizationFromDB()
{
    if (!m_delayedVisualization || !m_acquiring) {
        return;
    }

    try {
        // 查询最近的EEG数据
        QSqlQuery query;
        query.prepare("SELECT timestamp, fp1, fpz, fp2 FROM eeg_data "
                      "ORDER BY timestamp DESC LIMIT 250");

        if (!query.exec()) {
            qWarning() << "查询EEG数据失败:" << query.lastError().text();
            return;
        }

        // 准备数据点
        QVector<QVector<double>> dataPoints(3);
        QVector<qint64> timestamps;

        // 读取数据并添加到向量中
        while (query.next()) {
            qint64 timestamp = query.value(0).toLongLong();
            double fp1 = query.value(1).toDouble();
            double fpz = query.value(2).toDouble();
            double fp2 = query.value(3).toDouble();

            timestamps.prepend(timestamp);
            dataPoints[0].prepend(fp1);
            dataPoints[1].prepend(fpz);
            dataPoints[2].prepend(fp2);
        }

        // 如果有数据，发送给图表组件
        if (!dataPoints[0].isEmpty()) {
            // 发送批量数据
            for (int i = 0; i < dataPoints[0].size(); i++) {
                QVector<double> point;
                point.append(dataPoints[0][i]); // FP1
                point.append(dataPoints[1][i]); // FPZ
                point.append(dataPoints[2][i]); // FP2

                // 发送数据点
                emit allChannelsDataReady(point);

                // 单独发送每个通道的数据点
                for (int ch = 0; ch < 3; ch++) {
                    QVector<double> channelPoint;
                    channelPoint.append(dataPoints[ch][i]);
                    emit dataReady(channelPoint, ch);
                }
            }
        }
    } catch (const std::exception& e) {
        qWarning() << "从数据库更新可视化时发生异常:" << e.what();
    } catch (...) {
        qWarning() << "从数据库更新可视化时发生未知异常";
    }
}

void EEGDevice::saveDataToCSV()
{
    qDebug() << "开始将累积数据保存到CSV文件...";

    try {
        // 转换去噪数据为2D列表
        QVector<QVector<double>> denoisedData2D;
        for (const auto &batch : m_denoisedDataList) {
            for (int i = 0; i < batch[0].size(); ++i) {
                QVector<double> row;
                for (int ch = 0; ch < CHANNELS; ++ch) {
                    row.append(batch[ch][i]);
                }
                denoisedData2D.append(row);
            }
        }

        // 保存去噪值到CSV
        QString denoisedFilename = "去噪值_qt.csv";
        QFile denoisedFile(denoisedFilename);
        if (denoisedFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
            QTextStream out(&denoisedFile);
            for (const auto &row : denoisedData2D) {
                QStringList rowStrings;
                for (double val : row) {
                    rowStrings << QString::number(val);
                }
                out << rowStrings.join(",") << "\n";
            }
            denoisedFile.close();
            qDebug() << "去噪值已保存到" << denoisedFilename;
        } else {
            qWarning() << "无法打开文件保存去噪值:" << denoisedFilename;
        }

        // 保存原始值到CSV
        QString rawFilename = "原始值_qt.csv";
        QFile rawFile(rawFilename);
        if (rawFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
            QTextStream out(&rawFile);
            for (const auto &row : m_rawData) {
                QStringList rowStrings;
                for (unsigned char val : row) {
                    rowStrings << QString::number(val);
                }
                out << rowStrings.join(",") << "\n";
            }
            rawFile.close();
            qDebug() << "原始值已保存到" << rawFilename;
        } else {
            qWarning() << "无法打开文件保存原始值:" << rawFilename;
        }

        // 保存电压值到CSV
        QString voltageFilename = "电压值_qt.csv";
        QFile voltageFile(voltageFilename);
        if (voltageFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
            QTextStream out(&voltageFile);
            for (const auto &row : m_voltageData) {
                QStringList rowStrings;
                for (double val : row) {
                    rowStrings << QString::number(val);
                }
                out << rowStrings.join(",") << "\n";
            }
            voltageFile.close();
            qDebug() << "电压值已保存到" << voltageFilename;
        } else {
            qWarning() << "无法打开文件保存电压值:" << voltageFilename;
        }

        qDebug() << "所有数据已成功保存到CSV文件";
    } catch (const std::exception& e) {
        qWarning() << "保存数据到CSV时发生异常:" << e.what();
    } catch (...) {
        qWarning() << "保存数据到CSV时发生未知异常";
    }
}

bool EEGDevice::connect()
{
    qDebug() << "正在连接EEG设备...";

    // 如果已连接，先断开
    if (m_serialPort->isOpen()) {
        qDebug() << "EEG设备已连接，先断开连接";
        m_serialPort->close();
    }

    // 设置串口参数
    m_serialPort->setPortName(m_portName);
    m_serialPort->setBaudRate(m_baudRate);
    m_serialPort->setDataBits(QSerialPort::Data8);
    m_serialPort->setParity(QSerialPort::NoParity);
    m_serialPort->setStopBits(QSerialPort::OneStop);
    m_serialPort->setFlowControl(QSerialPort::NoFlowControl);

    qDebug() << "尝试打开串口:" << m_portName;

    // 打开串口
    if (!m_serialPort->open(QIODevice::ReadWrite)) {
        QString errorMsg = "无法打开串口: " + m_serialPort->errorString();
        qWarning() << errorMsg;
        emit errorOccurred(errorMsg);
        return false;
    }

    qDebug() << "串口打开成功，发送初始化命令";

    // 清空接收缓冲区
    m_serialPort->clear(QSerialPort::AllDirections);

    // 等待串口稳定
    QThread::msleep(100);

    // 发送初始化命令
    QByteArray initCommand = "uaisa";
    qint64 bytesWritten = m_serialPort->write(initCommand);
    qDebug() << "发送初始化命令:" << initCommand << "已写入" << bytesWritten << "字节";

    // 确保命令被发送
    if (!m_serialPort->waitForBytesWritten(1000)) {
        qWarning() << "发送初始化命令超时";
    }

    m_serialPort->flush();

    // 清空缓冲区
    m_frameBuffer.clear();
    m_voltageBuffer.clear();
    for (auto &channel : m_accumulatedData) {
        channel.clear();
    }
    for (auto &channel : m_referenceData) {
        channel.clear();
    }

    // 清空数据存储
    m_rawData.clear();
    m_voltageData.clear();
    m_denoisedDataList.clear();

    m_sampleCount = 0;
    m_isFrameStarted = false;

    // 设置连接状态
    m_connected = true;
    qDebug() << "EEG设备连接成功";
    emit connectionStatusChanged(true);

    return true;
}

bool EEGDevice::disconnect()
{
    // 如果正在采集，先停止
    if (isAcquiring()) {
        stopAcquisition();
    }

    // 关闭串口
    if (m_serialPort->isOpen()) {
        m_serialPort->close();
    }

    // 设置连接状态
    m_connected = false;
    emit connectionStatusChanged(false);

    return true;
}

bool EEGDevice::startAcquisition()
{
    // 检查是否已连接
    if (!isConnected()) {
        emit errorOccurred("设备未连接，无法开始采集");
        return false;
    }

    // 清空缓冲区
    QMutexLocker locker(&m_dataMutex);
    m_frameBuffer.clear();
    m_voltageBuffer.clear();

    // 清空通道数据，但保留容器结构并预分配空间
    for (auto &channel : m_accumulatedData) {
        channel.clear();
        channel.reserve(PROCESSING_BLOCK_SIZE * 2);
    }
    for (auto &channel : m_referenceData) {
        channel.clear();
        channel.reserve(PROCESSING_BLOCK_SIZE * 2);
    }

    // 清空数据存储
    m_rawData.clear();
    m_voltageData.clear();
    m_denoisedDataList.clear();

    // 清空可视化缓冲区
    m_visualBuffer.clear();

    // 清空所有通道的历史数据
    for (auto &history : m_channelHistory) {
        history.clear();
    }

    // 重置时间戳和计数器
    m_lastTimestamp = 0;
    m_sampleCount = 0;
    m_isFrameStarted = false;
    m_frameCounter = 0;
    locker.unlock();

    // 调整处理定时器频率，使其与可视化更新更同步
    // 从1000ms减少到200ms，更频繁地处理数据
    m_processingTimer->start(20);

    // 启动数据库更新定时器（用于延迟可视化）
    if (m_delayedVisualization) {
        m_dbUpdateTimer->start(40);
    }

    // 设置采集状态
    m_acquiring = true;
    emit acquisitionStatusChanged(true);

    qDebug() << "EEG设备开始采集数据";

    return true;
}

bool EEGDevice::stopAcquisition()
{
    // 停止处理定时器
    m_processingTimer->stop();

    // 停止数据库更新定时器
    m_dbUpdateTimer->stop();

    // 设置采集状态
    m_acquiring = false;
    emit acquisitionStatusChanged(false);

    qDebug() << "EEG设备停止采集数据";

    // 停止采集后，将数据存储到csv中
    if (!m_denoisedDataList.isEmpty()) {
        saveDataToCSV();
    }

    return true;
}

bool EEGDevice::isConnected() const
{
    return m_connected;
}

bool EEGDevice::isAcquiring() const
{
    return m_acquiring;
}


void EEGDevice::readSerialData()
{
    // 如果不在采集状态，只接收数据但不处理
    if (!m_acquiring) {
        m_serialPort->readAll();
        return;
    }

    try {
        // 读取可用数据
        QByteArray data = m_serialPort->readAll();

        // 将数据添加到帧缓冲区
        m_frameBuffer.append(data);

        // 处理完整的帧
        while (m_frameBuffer.size() >= 2) {
            // 查找帧起始标记 (0xA0, 0x10)
            if (!m_isFrameStarted &&
                m_frameBuffer.size() >= 2 &&
                static_cast<unsigned char>(m_frameBuffer.at(0)) == 0xA0 &&
                static_cast<unsigned char>(m_frameBuffer.at(1)) == 0x10) {
                m_isFrameStarted = true;
            }

            // 如果找到帧起始标记，检查是否有完整帧
            if (m_isFrameStarted) {
                if (m_frameBuffer.size() >= FRAME_SIZE) {
                    // 检查帧结束标记 (0xC0)
                    if (static_cast<unsigned char>(m_frameBuffer.at(FRAME_SIZE-1)) == 0xC0) {
                        // 提取完整帧
                        QByteArray frame = m_frameBuffer.left(FRAME_SIZE);
                        m_frameBuffer.remove(0, FRAME_SIZE);

                        // 解析帧 - 返回的是脑电信号通道的电压值（通道3-5）
                        QVector<double> voltages = parseFrame(frame);

                        // 如果解析成功，添加到电压缓冲区
                        if (voltages.size() == CHANNELS) {
                            QMutexLocker locker(&m_dataMutex);

                            // 添加到各通道的累积数据
                            for (int i = 0; i < CHANNELS; ++i) {
                                m_accumulatedData[i].append(voltages[i]);
                            }

                            m_sampleCount++;

                            // 增加帧计数器
                            m_frameCounter++;

                            // 如果不使用延迟可视化，则每5帧发送一次数据点
                            if (!m_delayedVisualization && m_frameCounter >= 5) {
                                m_frameCounter = 0;

                                // 发送单个数据点
                                QVector<double> dataPoint = voltages;
                                emit allChannelsDataReady(dataPoint);
                                emit dataReady(dataPoint, -1);

                                // 单独发送每个通道的数据
                                for (int i = 0; i < CHANNELS; i++) {
                                    QVector<double> channelPoint;
                                    channelPoint.append(voltages[i]);
                                    emit dataReady(channelPoint, i);
                                }
                            }
                        } else {
                            qWarning() << "帧解析失败，电压值数量不符";
                        }
                    } else {
                        // 帧无效，移除第一个字节
                        m_frameBuffer.remove(0, 1);
                        m_isFrameStarted = false;
                    }
                } else {
                    // 帧不完整，等待更多数据
                    break;
                }
            } else {
                // 移除无效字节
                m_frameBuffer.remove(0, 1);
            }
        }

        // 防止缓冲区过大
        if (m_frameBuffer.size() > 10000) {
            qWarning() << "EEG帧缓冲区过大，清空缓冲区";
            m_frameBuffer.clear();
            m_isFrameStarted = false;
        }
    } catch (const std::exception& e) {
        qWarning() << "读取串口数据时发生异常:" << e.what();
    } catch (...) {
        qWarning() << "读取串口数据时发生未知异常";
    }
}

//CSV文件处理
QVector<QVector<double>> EEGDevice::loadCSVData(const QString& filePath)
{
    QVector<QVector<double>> data;
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qWarning() << "无法打开CSV文件:" << filePath << "错误:" << file.errorString();
        return data;
    }

    QTextStream in(&file);
    int lineNumber = 0;

    while (!in.atEnd()) {
        QString line = in.readLine().trimmed();
        lineNumber++;

        // 跳过空行
        if (line.isEmpty()) {
            continue;
        }

        // 跳过可能的标题行
        if (lineNumber == 1 && (line.contains("FP1") || line.contains("Channel") || line.contains("通道"))) {
            continue;
        }

        // 解析数据行
        QStringList values = line.split(',');

        if (values.size() < 3) {
            qWarning() << "第" << lineNumber << "行数据不足3列，跳过:" << line;
            continue;
        }

        QVector<double> row;
        bool parseSuccess = true;

        // 解析前3列数据（FP1, FPZ, FP2）
        for (int i = 0; i < 3; i++) {
            bool ok;
            double value = values[i].trimmed().toDouble(&ok);

            if (!ok) {
                qWarning() << "第" << lineNumber << "行第" << (i+1) << "列数据解析失败:" << values[i];
                parseSuccess = false;
                break;
            }

            row.append(value);
        }

        if (parseSuccess) {
            data.append(row);
        }
    }

    file.close();

    qDebug() << "CSV文件加载完成，有效数据行数:" << data.size();
    return data;
}

bool EEGDevice::saveCSVData(const QVector<QVector<double>>& data, const QString& filePath)
{
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        qWarning() << "无法创建输出CSV文件:" << filePath << "错误:" << file.errorString();
        return false;
    }

    QTextStream out(&file);

    // 写入标题行
    out << "FP1_Filtered,FPZ_Filtered,FP2_Filtered\n";

    // 写入数据行
    int rowCount = data.size() > 0 ? data[0].size() : 0;
    for (int i = 0; i < rowCount; i++) {
        QStringList rowValues;
        for (int ch = 0; ch < data.size() && ch < 3; ch++) {
            if (i < data[ch].size()) {
                rowValues << QString::number(data[ch][i]);
            } else {
                rowValues << "0";
            }
        }
        out << rowValues.join(",") << "\n";
    }

    file.close();
    qDebug() << "滤波后的数据已保存到:" << filePath;
    return true;
}

bool EEGDevice::processCSVFile(const QString& inputFilePath, const QString& outputFilePath)
{
    qDebug() << "开始处理CSV文件:" << inputFilePath << "输出到:" << outputFilePath;

    try {
        // 发送进度信号
        emit csvProcessingProgress(0);

        // 检查文件是否存在
        if (!QFile::exists(inputFilePath)) {
            QString errorMsg = "输入文件不存在: " + inputFilePath;
            emit csvProcessingFinished(false, errorMsg);
            return false;
        }

        // 加载CSV数据
        emit csvProcessingProgress(10);
        QVector<QVector<double>> inputData = loadCSVData(inputFilePath);

        // 检查数据是否有效
        if (inputData.isEmpty()) {
            QString errorMsg = "CSV文件为空或格式无效";
            emit csvProcessingFinished(false, errorMsg);
            return false;
        }

        // 转置数据结构：从[行][通道]转为[通道][样本]
        emit csvProcessingProgress(20);
        QVector<QVector<double>> transposedData(3);
        int sampleCount = inputData.size();

        for (int ch = 0; ch < 3; ch++) {
            transposedData[ch].reserve(sampleCount);
        }

        for (int i = 0; i < sampleCount; i++) {
            if (inputData[i].size() >= 3) {
                transposedData[0].append(inputData[i][0]); // FP1
                transposedData[1].append(inputData[i][1]); // FPZ
                transposedData[2].append(inputData[i][2]); // FP2
            }
        }

        // 统计原始数据范围
        emit csvProcessingProgress(30);
        QVector<QPair<double, double>> originalRanges;
        for (int ch = 0; ch < 3; ch++) {
            if (!transposedData[ch].isEmpty()) {
                double min = *std::min_element(transposedData[ch].begin(), transposedData[ch].end());
                double max = *std::max_element(transposedData[ch].begin(), transposedData[ch].end());
                originalRanges.append(qMakePair(min, max));
                qDebug() << "通道" << ch << "原始数据范围:" << min << "到" << max;
            } else {
                originalRanges.append(qMakePair(0.0, 0.0));
            }
        }

        // 应用滤波处理 - 使用新的FFT滤波方法
        emit csvProcessingProgress(40);
        QVector<QVector<double>> processedData(3);

        for (int ch = 0; ch < 3; ch++) {
            // 对每个通道应用带通滤波
            processedData[ch] = applyBandpassFilter(transposedData[ch], m_lowCutoff, m_highCutoff, m_samplingRate);
        }

        // 统计处理后数据范围
        emit csvProcessingProgress(80);
        QVector<QPair<double, double>> processedRanges;
        for (int ch = 0; ch < 3; ch++) {
            if (!processedData[ch].isEmpty()) {
                double min = *std::min_element(processedData[ch].begin(), processedData[ch].end());
                double max = *std::max_element(processedData[ch].begin(), processedData[ch].end());
                processedRanges.append(qMakePair(min, max));
                qDebug() << "通道" << ch << "处理后数据范围:" << min << "到" << max;
            } else {
                processedRanges.append(qMakePair(0.0, 0.0));
            }
        }

        // 保存处理后的数据
        emit csvProcessingProgress(90);
        if (!saveCSVData(processedData, outputFilePath)) {
            QString errorMsg = "保存处理后的数据失败";
            emit csvProcessingFinished(false, errorMsg);
            return false;
        }

        // 准备成功消息
        QString successMsg = QString("CSV文件处理成功。\n\n"
                                     "处理前数据范围:\n"
                                     "FP1: %.2f 到 %.2f\n"
                                     "FPZ: %.2f 到 %.2f\n"
                                     "FP2: %.2f 到 %.2f\n\n"
                                     "处理后数据范围:\n"
                                     "FP1: %.2f 到 %.2f\n"
                                     "FPZ: %.2f 到 %.2f\n"
                                     "FP2: %.2f 到 %.2f\n\n"
                                     "已处理 %d 个数据点。\n"
                                     "结果已保存到: %s")
                                 .arg(originalRanges[0].first).arg(originalRanges[0].second)
                                 .arg(originalRanges[1].first).arg(originalRanges[1].second)
                                 .arg(originalRanges[2].first).arg(originalRanges[2].second)
                                 .arg(processedRanges[0].first).arg(processedRanges[0].second)
                                 .arg(processedRanges[1].first).arg(processedRanges[1].second)
                                 .arg(processedRanges[2].first).arg(processedRanges[2].second)
                                 .arg(sampleCount)
                                 .arg(QFileInfo(outputFilePath).fileName());

        // 完成处理
        emit csvProcessingProgress(100);
        emit csvProcessingFinished(true, successMsg);

        return true;
    } catch (const std::exception& e) {
        QString errorMsg = QString("处理CSV文件时发生异常: %1").arg(e.what());
        qWarning() << errorMsg;
        emit csvProcessingFinished(false, errorMsg);
        return false;
    } catch (...) {
        QString errorMsg = "处理CSV文件时发生未知异常";
        qWarning() << errorMsg;
        emit csvProcessingFinished(false, errorMsg);
        return false;
    }
}

// 添加陷波滤波器的设置函数
void EEGDevice::setNotchFilterEnabled(bool enabled)
{
    m_enableNotchFilter = enabled;
    qDebug() << "陷波滤波器已" << (enabled ? "启用" : "禁用");
}

bool EEGDevice::isNotchFilterEnabled() const
{
    return m_enableNotchFilter;
}

void EEGDevice::setNotchFrequency(double frequency)
{
    if (frequency > 0 && frequency < m_samplingRate / 2) {
        m_notchFrequency = frequency;
        qDebug() << "陷波频率设置为" << frequency << "Hz";
    } else {
        qWarning() << "无效的陷波频率:" << frequency << "Hz";
    }
}

double EEGDevice::getNotchFrequency() const
{
    return m_notchFrequency;
}

void EEGDevice::setNotchBandwidth(double bandwidth)
{
    if (bandwidth > 0 && bandwidth < m_samplingRate / 4) {
        m_notchBandwidth = bandwidth;
        qDebug() << "陷波带宽设置为" << bandwidth << "Hz";
    } else {
        qWarning() << "无效的陷波带宽:" << bandwidth << "Hz";
    }
}

double EEGDevice::getNotchBandwidth() const
{
    return m_notchBandwidth;
}

// 添加高通滤波器的设置函数
void EEGDevice::setHighpassFilterEnabled(bool enabled)
{
    m_enableHighpassFilter = enabled;
    qDebug() << "高通滤波器已" << (enabled ? "启用" : "禁用");
}

bool EEGDevice::isHighpassFilterEnabled() const
{
    return m_enableHighpassFilter;
}

// 实现陷波滤波器函数
QVector<double> EEGDevice::applyNotchFilter(const QVector<double>& data,
                                            double notchFreq,
                                            double bandwidth,
                                            double samplingRate)
{
    int n = data.size();

    // 检查输入数据是否有效
    if (n == 0) {
        qWarning() << "陷波滤波器输入数据为空";
        return data;
    }

    // 确保数据长度是2的幂，如果不是，则填充
    int paddedSize = 1;
    while (paddedSize < n) {
        paddedSize *= 2;
    }

    // 使用镜像填充而非零填充，减少边缘效应
    QVector<std::complex<double>> complexData(paddedSize, std::complex<double>(0, 0));

    // 复制数据到复数数组
    for (int i = 0; i < n; ++i) {
        complexData[i] = std::complex<double>(data[i], 0);
    }

    // 镜像填充剩余部分
    for (int i = n; i < paddedSize; ++i) {
        int mirrorIndex = 2 * n - i - 1;
        if (mirrorIndex >= 0 && mirrorIndex < n) {
            complexData[i] = std::complex<double>(data[mirrorIndex], 0);
        }
    }

    // 执行FFT
    fft(complexData, false);

    // 应用陷波滤波器
    double notchFreqNormalized = notchFreq / samplingRate;
    double bandwidthNormalized = bandwidth / samplingRate;

    for (int i = 0; i < paddedSize; ++i) {
        // 计算归一化频率
        double freq;
        if (i <= paddedSize / 2) {
            freq = static_cast<double>(i) / paddedSize;
        } else {
            freq = static_cast<double>(i - paddedSize) / paddedSize;
        }

        freq = qAbs(freq);

        // 陷波滤波：在陷波频率附近应用衰减
        double distance = qAbs(freq - notchFreqNormalized);
        if (distance < bandwidthNormalized / 2) {
            // 在陷波带宽内应用高斯衰减，使滤波更平滑
            double attenuation = 1.0 - exp(-pow(distance / (bandwidthNormalized / 4), 2));
            complexData[i] *= attenuation;
        }

        // 处理镜像频率（对称性）
        double mirrorFreq = 1.0 - freq;
        if (mirrorFreq > 0 && mirrorFreq < 1) {
            distance = qAbs(mirrorFreq - notchFreqNormalized);
            if (distance < bandwidthNormalized / 2) {
                double attenuation = 1.0 - exp(-pow(distance / (bandwidthNormalized / 4), 2));
                int mirrorIndex = (i <= paddedSize / 2) ? paddedSize - i : i - paddedSize;
                if (mirrorIndex >= 0 && mirrorIndex < paddedSize) {
                    complexData[mirrorIndex] *= attenuation;
                }
            }
        }
    }

    // 执行IFFT
    fft(complexData, true);

    // 提取实部作为结果
    QVector<double> result(n);
    for (int i = 0; i < n; ++i) {
        result[i] = complexData[i].real();
    }

    return result;
}
